package acn.spring.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@PropertySource("classpath:jdbc.properties")
@EnableJpaRepositories("acn.spring.backend.springDataJpa")
@EnableTransactionManagement
@Configuration
public class DataConfig {

	@Autowired
	Environment env;

	@Bean
	public DataSource dataSource() {

		DataSource dataSource = null;
		String databaseHSQL = env.getProperty("databaseHSQL");

		if ("yes".equals(databaseHSQL)) {
			EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
			builder.setType(EmbeddedDatabaseType.HSQL);
			builder.addScript("db/schema.sql");
			builder.addScript("db/test-data.sql");
			dataSource = builder.build();
		} else {
			dataSource = new DriverManagerDataSource();
			((DriverManagerDataSource) dataSource).setDriverClassName(env.getProperty("driverClassName"));
			((AbstractDriverBasedDataSource) dataSource).setUrl(env.getProperty("url"));
			((AbstractDriverBasedDataSource) dataSource).setUsername(env.getProperty("username"));
			((AbstractDriverBasedDataSource) dataSource).setPassword(env.getProperty("password"));
		}

		return dataSource;
	}

	@Bean
	public PlatformTransactionManager transactionManager() {
		return new JpaTransactionManager(entityManagerFactory().getObject());
	}

	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
		LocalContainerEntityManagerFactoryBean emfBeanFactory = new LocalContainerEntityManagerFactoryBean();
		emfBeanFactory.setDataSource(dataSource());
		emfBeanFactory.setJpaVendorAdapter(jpaVendorAdapter());
		emfBeanFactory.setPackagesToScan("acn.spring.domain");
		return emfBeanFactory;
	}

	@Bean
	public JpaVendorAdapter jpaVendorAdapter() {
		AbstractJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
		jpaVendorAdapter.setShowSql(true);
		jpaVendorAdapter.setGenerateDdl(true);
		// jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");
		jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.HSQLDialect");
		return jpaVendorAdapter;
	}
}
